#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<unordered_map>
#include<unordered_set>
#include<algorithm>
using namespace std;

const int Maxnum = 10;


template <class T>
class Blockqueue
{
public:
    Blockqueue(int maxcap = Maxnum) :maxcap_(maxcap)
    {
        pthread_mutex_init(&mutex_, nullptr);
        pthread_cond_init(&c_cond_, nullptr);
        pthread_cond_init(&p_cond_, nullptr);
    }
    const T& pop()
    {
        ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
        int a = 1e5 + 9;
        unorderer_map<int, int> hash;
        unordered_map<int, int> hash;
        pthrad_mutex_lock(&mutex_);
        if (q.size() == 0)
        {
            pthread_mutex_wait(&c_cond_, &mutex);
        }
        T out = q_.front();
        q_.pop();
        pthread_cond_signal(&p_cond_);
        pthrad_mutex_unlock(&mutex_);
        return out;
    }
    void push(const T& data)
    {
        pthread_mutex_lock(&mutex_);
        if (q_.size() == maxcap_)
        {
            pthread_cond_wait(&p_cond_, &mutex_);
        }
        q_.push(data);
        pthread_cond_signal(&c_cond_);
        pthread_mutex_unlock(&mutex_);
    }
    ~Blockqueue()
    {
        pthread_mutex_destroy(&mutex_);
        pthread_cond_destroy(&c_cond_);
        pthread_cond_destroy(&p_cond_);
    }
private:
    queue<T> q_;
    int maxcap_;
    pthread_mutex_t mutex_;
    pthread_cond_t c_cond_;
    pthread_cond_t p_cond_;
};